import { RouterContext } from '@koa/router'
import { Controller, Get } from 'koa-decorator-helpers'
import { getAccessTokenWithExpires, getJsApiTicket } from '~/data/token'
import { getSha1Signature } from '~/libs/wx/crypt'

@Controller({ prefix: '/api' })
export class Api {
    @Get('/jssdk')
    async jssdk(ctx: RouterContext) {
        const fail = (msg: string) => ({
            code: -1,
            msg,
        })

        let { app_id, component_app_id = '', url } = ctx.query
        if (typeof app_id !== 'string' || !app_id) {
            return fail('无效的参数 app_id')
        }
        if (typeof url !== 'string' || !url) {
            return fail('无效的参数 url')
        }
        if (typeof component_app_id !== 'string' || !component_app_id) {
            component_app_id = ''
        }

        const jsapi_ticket = await getJsApiTicket(app_id, component_app_id)
        if (!jsapi_ticket) {
            return fail('获取jsapi_ticket失败')
        }

        const timestamp = Math.floor(Date.now() / 1000)
        const noncestr = Math.random().toString().substring(0, 8)
        const signature = getSha1Signature(
            {
                timestamp: `timestamp=${timestamp}`,
                noncestr: `noncestr=${noncestr}`,
                jsapi_ticket: `jsapi_ticket=${jsapi_ticket}`,
                url: `url=${url}`,
            },
            '&',
        )

        return {
            appId: app_id,
            timestamp,
            nonceStr: noncestr,
            signature,
        }
    }

    @Get
    async accessToken(ctx: RouterContext) {
        const fail = (msg: string) => ({
            code: -1,
            msg,
        })

        let { app_id, component_app_id = '' } = ctx.query

        if (typeof app_id !== 'string' || !app_id) {
            return fail('无效的参数 app_id')
        }
        if (typeof component_app_id !== 'string' || !component_app_id) {
            component_app_id = ''
        }

        const data = await getAccessTokenWithExpires(app_id as string, component_app_id as string)

        return {
            access_token: data?.token ?? '',
            expires_in: data?.expires ?? 0,
        }
    }
}
